#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef WIN32
#include "windows.h"
#endif

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#include "pthread.h"

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include "BList.h"
#include "BVector.h"
#include "geometrics.h"
#include "quaternion.h"

#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"

#include "myglutaux.h"
#include "FTGLPolygonFont.h"
#include "AWLVP_DistanceMatrix.h"
#include "AWLocalViewport.h"
#include "AWLVP_NOOSMain.h"
#include "AWLVP_NOOSOntology.h"
#include "AWLVP_NOOSSummary.h"
#include "AWLVP_NOOS3DProjection.h"
#include "AWLVP_NOOS2DProjection.h"
#include "AWLVP_NOOSFTerm.h"
#include "AWLVP_NOOSTextFTerm.h"

#include "AWEntity.h"
#include "AWMessage.h"
#include "AWBody.h"
#include "AWMsgMoveBody.h"
#include "AWNOOSCBBody.h"

#include "CaseBaseUtils.h"

#include "loader.h"


extern int SCREEN_DX,SCREEN_DY;

AW_LVP_NOOSMain::AW_LVP_NOOSMain(int x,int y,int dx,int dy,FTKBase *cb,FTKBase *dm,AW_LVP_NOOSOntology *ontology_view,List<AW_LocalViewport> *viewports) : AW_LocalViewport(x,y,dx,dy)
{
	m_font=0;
	m_cb=cb;
	m_dm=dm;
	m_ontology_view=ontology_view;
	m_viewports=viewports;
	m_visualization_view=0;
	m_fterm_view=0;

	m_selected=0;
} /* AW_LVP_NOOSMain::AW_LVP_NOOSMain */ 


AW_LVP_NOOSMain::~AW_LVP_NOOSMain()
{
	m_cb=0;
	m_dm=0;
	m_ontology_view=0;
	m_viewports=0;
	m_visualization_view=0;
	m_fterm_view=0;

	m_selected=0;

	if (m_font!=0) {
//		delete m_font;
		m_font=0;
	}
} /* AW_LVP_NOOSMain::~AW_LVP_NOOSMain */ 



void AW_LVP_NOOSMain::draw_internal(void)
{
	int vpx=0,vpy=0,vpw=800,vph=600;
	float alpha=1.0F;

	// Test if a propers sort is selected in the ontology view:
	{
		Sort *s=m_ontology_view->get_selected_sort();
		if (s==0 || !is_a_case(s)) alpha=0.5F;
	}

	// Test if a new FTerm viewport has to be created:
	{
		if (m_fterm_view!=0 && m_fterm_view->get_ft()==0) {
			m_viewports->DeleteElement(m_fterm_view);
			delete m_fterm_view;
			m_fterm_view=0;
		} /* if */ 

		if (m_selected!=0) {
			if (m_fterm_view!=0) {
				m_viewports->DeleteElement(m_fterm_view);
				delete m_fterm_view;
				m_fterm_view=0;
			} /* if */ 

//			m_fterm_view=new AW_LVP_NOOSFTerm(m_viewport[0]+m_viewport[2]*0.38,
//											  m_viewport[1]+16,m_viewport[2]*0.60,m_viewport[3]-32,m_selected,m_dm);
			m_fterm_view=new AW_LVP_NOOSTextFTerm(m_viewport[0]+m_viewport[2]*0.38,
												  m_viewport[1]+16,m_viewport[2]*0.60,m_viewport[3]-32,m_selected,m_dm);
			m_viewports->Add(m_fterm_view);
			m_selected=0;
		} /* if */ 
	}
			
	if (m_font==0) {
		FILE *fp=fopen("arial.ttf","r");
		if (fp!=0) {
			fclose(fp);
			m_font=new FTGLPolygonFont("arial.ttf");
			m_font->FaceSize(2);
			m_font->Depth(0.2F);
		} /* if */ 
	} /* if */ 

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	{
		int tmp[4];
		glGetIntegerv(GL_VIEWPORT,tmp);
		vpx=tmp[0];
		vpy=tmp[1];
		vpw=tmp[2];
		vph=tmp[3];
	}
  
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

	glEnable(GL_BLEND);
	glColor4f(0.0F,0.0F,1.0F,0.5F);
	glTranslatef(0,0,0.02F);
	glutSolidBox(1,1,0.01F);
	glTranslatef(0,0,-0.04F);

	glPushMatrix();
	glScalef(0.5F,0.5F,0.5F);

	glPushName(1);
	glPushMatrix();
	glTranslatef(-1.20F,-1.5F,0);
	glColor3f(0.4F,0.6F,1.0F);
	glutSolidBox(0.25F,0.1F,0.1F);
	glTranslatef(0,0,-0.2F);
	if (m_font!=0) {
		float llx,lly,llz,urx,ury,urz;
		m_font->BBox( "Back", llx, lly, llz, urx, ury, urz);		
		glPushMatrix();
		glScalef(0.05F,0.05F,0.05F);
		glTranslatef(-(urx-llx)/2,-0.5F,0);
		glColor3f(1,1,1);
		m_font->Render("Back");
		glPopMatrix();
	} /* if */ 
	glPopMatrix();
	glPopName();

	glPushName(2);
	glPushMatrix();
	glTranslatef(-1.20F,-1.0F,0);
	glColor4f(0.4F,0.6F,1.0F,alpha);
	glutSolidBox(0.25F,0.1F,0.1F);
	glTranslatef(0,0,-0.2F);
	if (m_font!=0) {
		float llx,lly,llz,urx,ury,urz;
		m_font->BBox( "Summary", llx, lly, llz, urx, ury, urz);		
		glPushMatrix();
		glScalef(0.05F,0.05F,0.05F);
		glTranslatef(-(urx-llx)/2,-0.5F,0);
		glColor4f(1,1,1,alpha);
		m_font->Render("Summary");
		glPopMatrix();
	} /* if */ 
	glPopMatrix();
	glPopName();

	glPushName(3);
	glPushMatrix();
	glTranslatef(-1.20F,-0.50F,0);
	glColor4f(0.4F,0.6F,1.0F,alpha);
	glutSolidBox(0.35F,0.1F,0.1F);
	glTranslatef(0,0,-0.2F);
	if (m_font!=0) {
		float llx,lly,llz,urx,ury,urz;
		m_font->BBox( "3D Projection", llx, lly, llz, urx, ury, urz);		
		glPushMatrix();
		glScalef(0.05F,0.05F,0.05F);
		glTranslatef(-(urx-llx)/2,-0.5F,0);
		glColor4f(1,1,1,alpha);
		m_font->Render("3D Projection");
		glPopMatrix();
	} /* if */ 
	glPopMatrix();
	glPopName();

	glPushName(4);
	glPushMatrix();
	glTranslatef(-1.20F,-0.75F,0);
	glColor4f(0.4F,0.6F,1.0F,alpha);
	glutSolidBox(0.35F,0.1F,0.1F);
	glTranslatef(0,0,-0.2F);
	if (m_font!=0) {
		float llx,lly,llz,urx,ury,urz;
		m_font->BBox( "2D Projection", llx, lly, llz, urx, ury, urz);		
		glPushMatrix();
		glScalef(0.05F,0.05F,0.05F);
		glTranslatef(-(urx-llx)/2,-0.5F,0);
		glColor4f(1,1,1,alpha);
		m_font->Render("2D Projection");
		glPopMatrix();
	} /* if */ 
	glPopMatrix();
	glPopName();
	glDisable(GL_BLEND);        

	glColor4f(1,1,1,1);

	glPopMatrix();
	glPopMatrix();
} /* AW_LVP_NOOSMain::draw_internal */ 


bool AW_LVP_NOOSMain::MouseClick_internal(int selected)
{
	switch(selected) {
	case 1: /* BACK */ 
			return false;
			break;
	case 2: /* SUMMARY */ 
			{
				Sort *s=m_ontology_view->get_selected_sort();
				if (s!=0 && is_a_case(s)) {
					if (m_fterm_view!=0) {
						m_viewports->DeleteElement(m_fterm_view);
						delete m_fterm_view;
						m_fterm_view=0;
					} /* if */ 

					if (m_visualization_view!=0) {
						m_viewports->DeleteElement(m_visualization_view);
						delete m_visualization_view;
						m_visualization_view=0;
					} /* if */ 

					m_visualization_view=new AW_LVP_NOOSSummary(m_viewport[0]+m_viewport[2]*0.38,
																m_viewport[1]+16,m_viewport[2]*0.60,m_viewport[3]-32,s,m_cb);
					m_viewports->Add(m_visualization_view);
				} /* if */ 
			}
			break;
	case 3: /* 3D PROJECTION: */ 
	case 4:	/* 2D PROJECTION: */ 
			{
				Sort *s=m_ontology_view->get_selected_sort();
				NOOSDistanceMatrix *matrix=0;

				if (s!=0 && is_a_case(s)) {
					if (m_fterm_view!=0) {
						m_viewports->DeleteElement(m_fterm_view);
						delete m_fterm_view;
						m_fterm_view=0;
					} /* if */ 

					if (m_visualization_view!=0) {
						m_viewports->DeleteElement(m_visualization_view);
						delete m_visualization_view;
						m_visualization_view=0;
					} /* if */ 

					/* Find an apropriate distance matrix: */ 
					{
						List<NOOSDistanceMatrix> l,todelete;
						NOOSDistanceMatrix *m;
						l.Instance(m_distance_matrices);
						l.Rewind();
						while(l.Iterate(m)) {
							if (m->get_sort()==s) {
								if (m->need_to_recompute(m_cb,s)) {
									todelete.Add(m);
								} else {
									matrix=m;
								} /* if */ 
							} /* if */ 
						} /* while */ 

						while(!todelete.EmptyP()) {
							m=todelete.ExtractIni();
							m_distance_matrices.DeleteElement(m);
							delete m;
						} /* while */ 

						if (matrix==0) {
							matrix=new NOOSDistanceMatrix(m_cb,s);
							m_distance_matrices.Add(matrix);
						} /* if */ 
					}

					if (selected==3) {
						m_visualization_view=new AW_LVP_NOOS3DProjection(m_viewport[0]+m_viewport[2]*0.38,
																		 m_viewport[1]+16,m_viewport[2]*0.60,m_viewport[3]-32, matrix, &m_selected);
					} else {
						m_visualization_view=new AW_LVP_NOOS2DProjection(m_viewport[0]+m_viewport[2]*0.38,
																		 m_viewport[1]+16,m_viewport[2]*0.60,m_viewport[3]-32, matrix, &m_selected);
					} /* if */ 
					m_viewports->Add(m_visualization_view);
				} /* if */ 
			}
			break;
	} /* switch */ 
	
	return true;
} /* AW_LVP_NOOSMain::MouseClick */ 